package com.sfzd5.UI;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.sfzd5.aiclassroom.modle.*;
import com.sfzd5.exam.helplibrary.Generator;
import com.sfzd5.aiclassroom.PostAnserResult;
import com.sfzd5.exam.helplibrary.exam.ExamInof;
import com.sfzd5.exam.helplibrary.exam.answersheet.AnswerSheetQuestion;
import com.sfzd5.exam.helplibrary.exam.answersheet.Area;
import com.sfzd5.exam.helplibrary.taskstatisitcs.*;
import org.apache.commons.io.FileUtils;
import org.java_websocket.WebSocket;
import org.java_websocket.drafts.Draft_6455;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;

import javax.swing.*;
import javax.swing.border.TitledBorder;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.AbstractTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Type;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.text.NumberFormat;
import java.util.*;
import java.util.List;

public class DataForm {
    public JPanel mPanel;
    private JButton 关闭Button;
    private JPanel piePanel;
    private JLabel lb_msg;

    //StuInfo
    private JScrollPane stuScrollPane;
    private JTable wTable;
    WTableModel dataModel;

    //QuestionInfo
    //private JList qList;
    private JScrollPane qPanel;
    private JButton 查看学生答案Button;
    private JButton 保存数据Button;
    private JPanel qiPanel;
    private JButton 载入数据Button;
    private JButton 数据统计Button;
    private JButton 查看习题答案Button;

    HashMap<Long, QuestionInfoPanel> questionInfoPanelMap;

    TaskStatistics taskStatistics;
    PieChartHelper pieChartHelper;

    ExamQuestionsInfo task;
    ExamInof answerSheetExamInof;

    WsServer server;

    public DataForm(ExamQuestionsInfo task) {
        this.task = task;

        //载入答题卡信息，用来传递给扫描APP
        File pdfFilePath = new File(HomeWorkManager.examDir, String.valueOf(task.id));
        File kFile = new File(pdfFilePath, task.id + ".json");
        if (kFile.exists()) {
            try {
                String examInfoJson = FileUtils.readFileToString(kFile, "utf-8");
                answerSheetExamInof = new Gson().fromJson(examInfoJson, ExamInof.class);
                answerSheetExamInof.cleanAreaList();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        } else {
            answerSheetExamInof = task.toExamInfo();
        }

        qPanel.getVerticalScrollBar().setUI(new DemoScrollBarUI());
        stuScrollPane.getVerticalScrollBar().setUI(new DemoScrollBarUI());

        VerticalFlowLayout vfl1 = new VerticalFlowLayout();
        vfl1.setVGap(10);
        qiPanel.setLayout(vfl1);

        //初始化数据中心
        taskStatistics = new TaskStatistics(this.task);

        //开始服务
        startServer();

        关闭Button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    server.stop();
                } catch (IOException e1) {
                    e1.printStackTrace();
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
            }
        });

        //初始化饼图
        TotalInfo totalInfo = taskStatistics.getTotalInfo();
        pieChartHelper = new PieChartHelper(totalInfo);
        piePanel.setPreferredSize(new Dimension(300, 300));
        piePanel.add(pieChartHelper.geChartPanel(), BorderLayout.CENTER);

        //初始化学生列表
        Collections.sort(taskStatistics.stuInfoList, stuInfoComparator);
        dataModel = new WTableModel();
        wTable.setModel(dataModel);

        关闭Button.setEnabled(true);

        //习题显示Panel的map
        questionInfoPanelMap = new HashMap<>();
        for (QuestionInfo qi : taskStatistics.questionInfoList) {
            QuestionInfoPanel p = new QuestionInfoPanel(taskStatistics, qi.q.id);
            qiPanel.add(p.mPanel);
            questionInfoPanelMap.put(qi.q.id, p);
            p.setQuestionClickListener(new QuestionClickListener() {
                @Override
                public void QuestionClick(QuestionInfo questionInfo) {
                    QuestionInfoDialog questionInfoDialog = new QuestionInfoDialog(
                            Generator.generateQuestionHtml_forPanelOnlyQuestion(questionInfo.q),
                            questionInfo.getRate()
                    );
                    questionInfoDialog.setTitle("习题讲解");
                    questionInfoDialog.setPreferredSize(new Dimension(1100, 700));
                    questionInfoDialog.pack();
                    questionInfoDialog.setVisible(true);
                }
            });
        }

        // 查看全部学生的全部主观题回复
        查看学生答案Button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //showTasksubmitPics();
                File htmlFile = createHtml();
                try {
                    Desktop.getDesktop().open(htmlFile);
                } catch (IOException ioException) {
                    ioException.printStackTrace();
                }
            }
        });

        保存数据Button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                File pdfFilePath = new File(HomeWorkManager.examDir, String.valueOf(task.id));
                File file = new File(pdfFilePath, +task.id + "学生答案.json");
                String json = new Gson().toJson(taskStatistics.getTasksubmitMap());
                try {
                    FileUtils.writeStringToFile(file, json, "utf-8");
                    lb_msg.setText("已保存");
                } catch (IOException ioException) {
                    ioException.printStackTrace();
                }
            }
        });
        载入数据Button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                File pdfFilePath = new File(HomeWorkManager.examDir, String.valueOf(task.id));
                File file = new File(pdfFilePath, +task.id + "学生答案.json");
                if (file.exists()) {
                    try {
                        String json = FileUtils.readFileToString(file, "utf-8");
                        //HashMap<Long, List<Tasksubmit>>
                        Type type = new TypeToken<Map<Long, List<Tasksubmit>>>() {
                        }.getType();
                        Map<Long, List<Tasksubmit>> map = new Gson().fromJson(json, type);

                        for (long stuid : map.keySet()) {
                            if (!taskStatistics.hasStu(stuid)) {
                                taskStatistics.addTasksubmits(map.get(stuid));
                            }
                        }
                        Collections.sort(taskStatistics.stuInfoList, stuInfoComparator);
                        resetDataUI();

                    } catch (IOException ioException) {
                        ioException.printStackTrace();
                    }
                }
            }
        });
        数据统计Button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //task
                HashMap<String, KnowledgeCount> knowledgeCountMap = new HashMap<>();
                for (QuestionInfo qi : taskStatistics.questionInfoList) {
                    for (String k : qi.q.knowledges) {
                        KnowledgeCount c;
                        if (!knowledgeCountMap.containsKey(k)) {
                            c = new KnowledgeCount(k);
                            knowledgeCountMap.put(k, c);
                        } else {
                            c = knowledgeCountMap.get(k);
                        }
                        c.rightCount += qi.rightCount;
                        c.totalCount += qi.overCount;
                    }
                }

                StringBuilder sb = new StringBuilder();
                sb.append("知识点,正确数,提交总\n");
                for (String k : knowledgeCountMap.keySet()) {
                    KnowledgeCount c = knowledgeCountMap.get(k);
                    sb.append(c.knowledge).append(",").append(c.rightCount).append(",").append(c.totalCount).append("\n");
                }

                File pdfFilePath = new File(HomeWorkManager.examDir, String.valueOf(task.id));
                File file = new File(pdfFilePath, +task.id + "知识点统计.csv");
                try {
                    FileUtils.writeStringToFile(file, sb.toString(), "utf-8");
                    lb_msg.setText("已保存");
                } catch (IOException ioException) {
                    ioException.printStackTrace();
                }

            }
        });
    }

    //在此生成html文件，调用浏览器打开
    void showTasksubmitPics() {
        PicsDialog picsDialog = new PicsDialog(taskStatistics, answerSheetExamInof);
        int screenHeight = 600;
        int screenWidth = 800;
        Dimension d = new Dimension(screenWidth, screenHeight);
        picsDialog.setSize(d);
        picsDialog.setPreferredSize(d);
        picsDialog.pack();
        picsDialog.setVisible(true);
    }


    public File createHtml() {
        StringBuilder html = new StringBuilder();
        taskStatistics.stuInfoList.sort(new Comparator<StuInfo>() {
            @Override
            public int compare(StuInfo o1, StuInfo o2) {
                return Long.compare(o1.id, o2.id);
            }
        });

        HashMap<Long, List<Tasksubmit>> tasksubmitMap = taskStatistics.getTasksubmitMap();

        html.append("<!DOCTYPEhtml>\n<html>\n<head>\n<meta charset='utf-8'/>\n<link href='../jquery-ui.css' rel='stylesheet'>\n</head>\n<body>\n");
        html.append("<h2 class='demoHeaders'>主观题学生答案</h2>\n");
        html.append("<div id='accordion'>\n");
        for (StuInfo stu : taskStatistics.stuInfoList) {
            html.append("<h3>学生：").append(stu.name).append("</h3>\n");//添加学生姓名
            html.append("<div>\n");
            List<Tasksubmit> tasksubmitList = tasksubmitMap.get(stu.id);
            for (Area area : answerSheetExamInof.areaList) {
                if (area.areaType != Area.AreaType.Choice) {
                    for (AnswerSheetQuestion asq : area.answerSheetQuestionList) {
                        //根据 asq.questionId 查询 TasksubmitList，找到图片
                        Tasksubmit tasksubmit = null;
                        for (Tasksubmit ts : tasksubmitList) {
                            if (ts.student_id == stu.id && asq.questionId == ts.question_id) {
                                tasksubmit = ts;
                                break;
                            }
                        }
                        if (tasksubmit != null) {
                            html.append("<div class='answer'><img src='data:image/jpeg;base64,").append(tasksubmit.answerBase64Pic).append("' /></div>\n");
                        }
                    }
                }
            }
            html.append("</div>\n");
        }
        html.append("</div>\n");
        html.append("<script src='../jquery.js'></script>\n<script src='../jquery-ui.js'></script>\n");
        html.append("<script>$( \"#accordion\" ).accordion();</script>\n");
        html.append("</body>\n</html>");

        File pdfFilePath = new File(HomeWorkManager.examDir, String.valueOf(task.id));
        File file = new File(pdfFilePath, +task.id + "学生主观题答案.html");
        try {
            FileUtils.writeStringToFile(file, html.toString(), "utf-8");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file;
    }

    Comparator<QuestionInfo> qComparator = new Comparator<QuestionInfo>() {
        @Override
        public int compare(QuestionInfo o1, QuestionInfo o2) {
            return Float.compare(o1.getRate(), o2.getRate());
        }
    };

    Comparator<StuInfo> stuInfoComparator = new Comparator<StuInfo>() {
        @Override
        public int compare(StuInfo o1, StuInfo o2) {
            return Float.compare(o2.getRightRate(), o1.getRightRate());
        }
    };

    {
// GUI initializer generated by IntelliJ IDEA GUI Designer
// >>> IMPORTANT!! <<<
// DO NOT EDIT OR ADD ANY CODE HERE!
        $$$setupUI$$$();
    }

    /**
     * Method generated by IntelliJ IDEA GUI Designer
     * >>> IMPORTANT!! <<<
     * DO NOT edit this method OR call it in your code!
     *
     * @noinspection ALL
     */
    private void $$$setupUI$$$() {
        mPanel = new JPanel();
        mPanel.setLayout(new BorderLayout(0, 0));
        final JToolBar toolBar1 = new JToolBar();
        mPanel.add(toolBar1, BorderLayout.NORTH);
        关闭Button = new JButton();
        关闭Button.setText("关闭");
        toolBar1.add(关闭Button);
        查看学生答案Button = new JButton();
        查看学生答案Button.setText("查看学生答案");
        toolBar1.add(查看学生答案Button);
        保存数据Button = new JButton();
        保存数据Button.setText("保存数据");
        toolBar1.add(保存数据Button);
        载入数据Button = new JButton();
        载入数据Button.setText("载入数据");
        toolBar1.add(载入数据Button);
        数据统计Button = new JButton();
        数据统计Button.setText("数据统计");
        toolBar1.add(数据统计Button);
        lb_msg = new JLabel();
        lb_msg.setText("已连接");
        toolBar1.add(lb_msg);
        final JPanel panel1 = new JPanel();
        panel1.setLayout(new com.intellij.uiDesigner.core.GridLayoutManager(3, 1, new Insets(8, 16, 8, 16), -1, -1));
        mPanel.add(panel1, BorderLayout.WEST);
        final JLabel label1 = new JLabel();
        label1.setText("进度");
        panel1.add(label1, new com.intellij.uiDesigner.core.GridConstraints(0, 0, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_WEST, com.intellij.uiDesigner.core.GridConstraints.FILL_NONE, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        piePanel = new JPanel();
        piePanel.setLayout(new BorderLayout(0, 0));
        panel1.add(piePanel, new com.intellij.uiDesigner.core.GridConstraints(1, 0, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_BOTH, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
        stuScrollPane = new JScrollPane();
        panel1.add(stuScrollPane, new com.intellij.uiDesigner.core.GridConstraints(2, 0, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_BOTH, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_WANT_GROW, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_WANT_GROW, null, new Dimension(300, -1), new Dimension(300, -1), 0, false));
        stuScrollPane.setBorder(BorderFactory.createTitledBorder(null, "学生信息", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, null, null));
        wTable = new JTable();
        stuScrollPane.setViewportView(wTable);
        final JPanel panel2 = new JPanel();
        panel2.setLayout(new BorderLayout(0, 0));
        mPanel.add(panel2, BorderLayout.CENTER);
        panel2.setBorder(BorderFactory.createTitledBorder(null, "习题数据", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, null, null));
        qPanel = new JScrollPane();
        panel2.add(qPanel, BorderLayout.CENTER);
        qiPanel = new JPanel();
        qiPanel.setLayout(new com.intellij.uiDesigner.core.GridLayoutManager(1, 1, new Insets(0, 0, 0, 0), -1, -1));
        qPanel.setViewportView(qiPanel);
    }

    /**
     * @noinspection ALL
     */
    public JComponent $$$getRootComponent$$$() {
        return mPanel;
    }

    /**
     * websocket部分
     */
    class WsServer extends WebSocketServer {
        int counter = 0;
        int port = 9002;

        public String WsServerAddress() throws UnknownHostException {
            InetAddress addr = InetAddress.getLocalHost();
            return "ws://" + addr.getHostAddress() + ":" + port;
        }

        public WsServer() throws UnknownHostException {
            super(new InetSocketAddress(9002), Collections.singletonList(new Draft_6455()));
            this.setConnectionLostTimeout(0);
        }

        @Override
        public void onMessage(WebSocket webSocket, String s) {
            if (s.indexOf("PostAnserResult") > 0) {
                PostAnserResult param = new Gson().fromJson(s, PostAnserResult.class);
                if (param.tasksubmits != null && param.tasksubmits.size() > 0) {
                    if (!taskStatistics.hasStu(param.tasksubmits.get(0).student_id)) {
                        taskStatistics.addTasksubmits(param.tasksubmits);

                        Collections.sort(taskStatistics.stuInfoList, stuInfoComparator);
                        SwingUtilities.invokeLater(new Runnable() {
                            @Override
                            public void run() {
                                resetDataUI();
                            }
                        });
                    }
                }
            } else {
                System.out.println(s);
            }
        }

        @Override
        public void onOpen(WebSocket webSocket, ClientHandshake clientHandshake) {
            System.out.println("客户端连接");
            webSocket.send(new Gson().toJson(answerSheetExamInof));
        }

        @Override
        public void onClose(WebSocket webSocket, int i, String s, boolean b) {
        }

        @Override
        public void onError(WebSocket webSocket, Exception e) {
        }

        @Override
        public void onStart() {
            System.out.println("WebSocket Server started!");
            try {
                lb_msg.setText("WS服务器地址：" + WsServerAddress());
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
        }
    }

    private void startServer() {
        //websocket连接
        try {
            server = new WsServer();
            server.start();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }

    //初始化界面,此时已经成功获取所有习题,学生信息,学生提交的答案
    private void resetDataUI() {
        TotalInfo totalInfo = taskStatistics.getTotalInfo();
        pieChartHelper.resetPieChart(totalInfo);

        dataModel.fireTableDataChanged();
        for (QuestionInfoPanel p : questionInfoPanelMap.values()) {
            p.resetInfo();
        }
    }

    String[] columnNames = {"学生", "进度", "正确率", "主观题"};

    class WTableModel extends AbstractTableModel {

        NumberFormat format;

        WTableModel() {
            format = NumberFormat.getPercentInstance();
            format.setMaximumFractionDigits(2);
        }

        @Override
        public int getRowCount() {
            return taskStatistics.stuInfoList.size();
        }

        @Override
        public int getColumnCount() {
            return columnNames.length;
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            StuInfo stuInfo = taskStatistics.stuInfoList.get(rowIndex);

            if (columnIndex == 0) {
                return stuInfo.name;
            } else if (columnIndex == 1) {
                return stuInfo.overCount;
            } else if (columnIndex == 2) {
                return format.format(stuInfo.getRightRate());
            } else if (columnIndex == 3) {
                return String.valueOf(stuInfo.otherCount);
            }
            return "";
        }

        @Override
        public String getColumnName(int column) {
            return columnNames[column];
        }
    }
}
